#ifndef _CANARY2_CORO_EPOLL_SLEEPER_H_
#define _CANARY2_CORO_EPOLL_SLEEPER_H_

#include "epoll_suspended_manager.h"
#include "../sys/sleeper_concepts.h"
#include "../sys/timerbase.h"

namespace wilson::coro
{
    class epoll_sleeper
    {
    public:    
        epoll_sleeper(epoll_suspend_manager& mgr, sys::timerbase& timer)
            : es_suspend_mgr{ mgr }, es_timer{ timer }
        {
        }

        void operator()(
            ::std::chrono::milliseconds timeout 
            = ::std::chrono::milliseconds{3000}) noexcept
        {
            auto timer_ask_timeout = 
                ::std::chrono::duration_cast<::std::chrono::milliseconds>(
                    es_timer.pioneer() - ::std::chrono::system_clock::now()
                );
            timeout = ::std::min(
                timeout, timer_ask_timeout
            );
            if (timeout.count() <= 0) timeout = ::std::chrono::milliseconds{0};
            es_suspend_mgr.wait_and_schedule(timeout);
            es_timer.do_all_timeout();
        }

        void awake() noexcept
        {
            es_suspend_mgr.awake();
        }

        bool done() const noexcept
        {
            return es_suspend_mgr.done() && es_timer.done();
        }

        auto& suspend_manager() { return es_suspend_mgr; }

    private:
        epoll_suspend_manager& es_suspend_mgr;
        sys::timerbase& es_timer;
    };
}

#endif
